package controllers

import (
	"encoding/json"
	"fmt"
	_ "gitchina/kly_service/errors"
	"gitchina/kly_service/models"
	"gitchina/kly_service/util"
	"time"

	"gitchina/kly_service/models/qpay"
	"github.com/astaxie/beego"
	"strconv"
)

type PayController struct {
	beego.Controller
}

// @router /105001 [post]
func (ctrl *PayController) Pay() {
	var rq models.PayParam
	memberId := models.ID(ctrl.Ctx.Input.GetData("mbrId").(string))
	if err := json.Unmarshal(ctrl.Ctx.Input.RequestBody, &rq); err == nil {
		rcvUrl := fmt.Sprintf("%sv1/api/105002", beego.AppConfig.String("domain"))
		if rs, err := models.Pay(memberId, rq.WaybillId, rq.Pwd, rcvUrl, rq.PayType, rq.CardID); err == nil {
			ctrl.Data["json"] = models.NewOkResponse(rs)
		} else {
			ctrl.Data["json"] = models.NewFailResponse(err)
		}
		ctrl.ServeJSON()
	} else {
		ctrl.Ctx.ResponseWriter.WriteHeader(400)
	}
}

// @router /105002 [post]
func (ctrl *PayController) PostPay() {
	util.GetLogger().Debug("=================>form:%v", ctrl.Ctx.Request.Form)
	if errorCode, ok := models.IsAllInPaySucc(ctrl.Ctx.Request.Form); ok {
		if payId, _, payData, amount, ok := models.GetAndVerifyAllInPay(ctrl.Ctx.Request.Form); ok {
			util.GetLogger().Debug("=================>paydata:%v", payData)
			if err := models.PostPay(models.ID(payId), amount/100, models.PostPayItem{PayOk: ok, Message: "", CallbackData: payData}); err != nil {
				util.GetLogger().Error("[ctrl-PostPay] - error:%s. [id:%s] ", err.Error(), ctrl.Ctx.Request.Form.Get("orderNo"))
			}
		} else {
			util.GetLogger().Error("[ctrl-PostPay] - error:verify sign failed. [id%s]", ctrl.Ctx.Request.Form.Get("orderNo"))
		}
	} else {
		util.GetLogger().Error("[ctrl-PostPay] - error:code:%s. [id%s]", errorCode, ctrl.Ctx.Request.Form.Get("orderNo"))
	}
}

// @router /105003 [post]
func (ctrl *PayController) TopUp() {
	var rq models.TopUpRQ
	memberId := models.ID(ctrl.Ctx.Input.GetData("mbrId").(string))
	if err := json.Unmarshal(ctrl.Ctx.Input.RequestBody, &rq); err == nil {
		if rs, err := models.TopUp(memberId, rq.PayPwd, rq.Amount); err == nil {
			rs.CreateTime = time.Now().Format("2006-01-02 15:04:05")
			ctrl.Data["json"] = models.NewOkResponse(rs)
		} else {
			ctrl.Data["json"] = models.NewFailResponse(err)
		}
		ctrl.ServeJSON()
	} else {
		ctrl.Ctx.ResponseWriter.WriteHeader(400)
	}
}

// @router /105004 [post]
func (ctrl *PayController) GetBankDetailList() {
	var rq models.PagedRQ
	memberId := models.ID(ctrl.Ctx.Input.GetData("mbrId").(string))
	if err := json.Unmarshal(ctrl.Ctx.Input.RequestBody, &rq); err == nil {
		if rs, err := models.GetBankDetailList(memberId, rq.PageNo, rq.PageSize); err == nil {
			ctrl.Data["json"] = models.NewOkResponse(rs)
		} else {
			ctrl.Data["json"] = models.NewFailResponse(err)
		}
		ctrl.ServeJSON()
	} else {
		ctrl.Ctx.ResponseWriter.WriteHeader(400)
	}
}

// @router /105005 [post]
func (ctrl *PayController) GetTransFlowList() {
	var rq models.PagedRQ
	memberId := models.ID(ctrl.Ctx.Input.GetData("mbrId").(string))
	if err := json.Unmarshal(ctrl.Ctx.Input.RequestBody, &rq); err == nil {
		if rs, err := models.GetTransFlowList(memberId, rq.PageNo, rq.PageSize); err == nil {
			ctrl.Data["json"] = models.NewOkResponse(rs)
		} else {
			ctrl.Data["json"] = models.NewFailResponse(err)
		}
		ctrl.ServeJSON()
	} else {
		ctrl.Ctx.ResponseWriter.WriteHeader(400)
	}
}

// @router /105006 [post]
func (ctrl *PayController) Refund() {

}

// @router /105007 [post]
func (ctrl *PayController) GetPayAmountDetail() {
	var rq models.GetPaymentAmountDetailRQ
	memberId := models.ID(ctrl.Ctx.Input.GetData("mbrId").(string))
	if err := json.Unmarshal(ctrl.Ctx.Input.RequestBody, &rq); err == nil {
		if rs, err := models.GetPaymentAmountDetail(models.ID(rq.PayId), memberId); err == nil {
			ctrl.Data["json"] = models.NewOkResponse(rs)
		} else {
			ctrl.Data["json"] = models.NewFailResponse(err)
		}
		ctrl.ServeJSON()
	} else {
		ctrl.Ctx.ResponseWriter.WriteHeader(400)
	}
}

// @router /105008 [post]
func (ctrl *PayController) QPayNotify() {
	util.GetLogger().Debug("=================>form:%v", ctrl.Ctx.Request.Form)

	p := qpay.NewPayment()
	ok, undecoded := p.Accept(ctrl.Ctx.Request.Form)
	if !ok {
		util.GetLogger().Error("[QPayNotify] - error:accept failed")
		ctrl.Ctx.WriteString("error")
		return
	}

	amount, err := strconv.ParseFloat(p.TrxAmount(), 32)
	if err != nil {
		util.GetLogger().Error("[QPayNotify] - error:invalid amount")
		ctrl.Ctx.WriteString("error")
		return
	}
	err = models.PostPay(models.ID(p.ID()), float32(amount)/100, models.PostPayItem{
		PayOk:        true,
		Message:      "",
		CallbackData: undecoded,
	})
	if err != nil {
		util.GetLogger().Error("[QPayNotify] - error:%s", err.Error())
		ctrl.Ctx.WriteString("error")
		return
	}
	ctrl.Ctx.WriteString("success")
}

// @router /105009 [post]
func (ctrl *PayController) QPayConfirm() {
	var rq models.QPayConfirmRQ
	memberId := models.ID(ctrl.Ctx.Input.GetData("mbrId").(string))
	if err := json.Unmarshal(ctrl.Ctx.Input.RequestBody, &rq); err == nil {
		if err := models.PayConfirm(memberId, models.ID(rq.PayID), 1, rq.SMSCode); err == nil {
			ctrl.Data["json"] = models.NewOkResponse(nil)
		} else {
			ctrl.Data["json"] = models.NewFailResponse(err)
		}
		ctrl.ServeJSON()
	} else {
		ctrl.Ctx.ResponseWriter.WriteHeader(400)
	}
}

// @router /105099 [post]
func (ctrl *PayController) PayDebug() {
	env := beego.BConfig.RunMode
	if env != "test" && env != "dev" {
		ctrl.Ctx.ResponseWriter.WriteHeader(403)
	} else {
		var rq models.GetPaymentAmountDetailRQ
		mid := models.ID(ctrl.Ctx.Input.GetData("mbrId").(string))
		if err := json.Unmarshal(ctrl.Ctx.Input.RequestBody, &rq); err == nil {
			if err := models.AutoPayOnlyForTest(mid, models.ID(rq.PayId)); err == nil {
				ctrl.Data["json"] = models.NewOkResponse(nil)
			} else {
				ctrl.Data["json"] = models.NewFailResponse(err)
			}
			ctrl.ServeJSON()
		} else {
			ctrl.Ctx.ResponseWriter.WriteHeader(400)
		}
	}
}

// @router /105100 [post]
func (ctrl *PayController) GetOfflinePayInfoList() {
	mbrId := models.ID(ctrl.Ctx.Input.GetData("mbrId").(string))
	if list, err := models.GetOfflinePayInfoList(mbrId); err == nil {
		ctrl.Data["json"] = models.NewOkResponse(list)
	} else {
		ctrl.Data["json"] = models.NewFailResponse(err)
	}
	ctrl.ServeJSON()
}

// @router /105101 [post]
func (ctrl *PayController) GetOfflinePayInfo() {
	var rq models.OfflinePayInfoRQ
	if err := json.Unmarshal(ctrl.Ctx.Input.RequestBody, &rq); err == nil {
		if rs, err := models.GetOfflinePayInfoByWaybillID(models.ID(rq.WaybillID)); err == nil {
			ctrl.Data["json"] = models.NewOkResponse(rs)
		} else {
			ctrl.Data["json"] = models.NewFailResponse(err)
		}
		ctrl.ServeJSON()
	} else {
		ctrl.Ctx.ResponseWriter.WriteHeader(400)
	}
}
